package com.molichuxing.gateway.bff.order.services.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.molichuxing.framework.dto.Paged;
import com.molichuxing.framework.dto.TabDto;
import com.molichuxing.framework.exception.BizException;
import com.molichuxing.framework.result.ResponseResult;
import com.molichuxing.framework.utils.DingTalkUtil;
import com.molichuxing.framework.utils.EmailUtil;
import com.molichuxing.gateway.bff.order.entity.request.modify.OrderDeliverySlipModifyVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerCarVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerContractVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerDetailBasicVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerDetailCarInfoVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerDetailStartVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerDetailVehicleVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerStatusInfoVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerStatusVo;
import com.molichuxing.gateway.bff.order.entity.response.OrderDealerVo;
import com.molichuxing.gateway.bff.order.services.OrderDealerBffService;
import com.molichuxing.gateway.property.EmailSubjectEnum;
import com.molichuxing.gateway.property.EmailTemplateEnum;
import com.molichuxing.gateway.utils.RequestAttrUtil;
import com.molichuxing.gateway.utils.TokenUtil;
import com.molichuxing.gateway.utils.entity.UserEntity;
import com.molichuxing.services.business.dto.request.modify.StockCarBizModifyDto;
import com.molichuxing.services.business.dto.response.ContractImageBizDto;
import com.molichuxing.services.business.dto.response.ContractPurchaseBizDto;
import com.molichuxing.services.business.dto.response.OrderDealerBizDto;
import com.molichuxing.services.business.dto.response.OrderDealerDeliveryBizDto;
import com.molichuxing.services.business.dto.response.OrderDealerDetailCarInfoBizDto;
import com.molichuxing.services.business.dto.response.OrderDealerDetailStartBizDto;
import com.molichuxing.services.business.dto.response.OrderDealerStatusBizDto;
import com.molichuxing.services.business.dto.response.OrderDealerStatusInfoBizDto;
import com.molichuxing.services.business.service.ContractBizService;
import com.molichuxing.services.business.service.OrderDealerBizService;
import com.molichuxing.services.business.service.OrderTradeFlowBizService;
import com.molichuxing.services.business.service.StockCarBizService;
import com.molichuxing.services.business.service.VehicleBizService;
import com.molichuxing.services.infrastructure.dto.request.create.FenceExceptionCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.IovFenceBindingCreateDto;
import com.molichuxing.services.infrastructure.dto.request.create.OrderStatusFlowCreateDto;
import com.molichuxing.services.infrastructure.dto.request.modify.DeliverySlipModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.IovFenceBindingModifyDto;
import com.molichuxing.services.infrastructure.dto.request.modify.RefuseModifyFto;
import com.molichuxing.services.infrastructure.dto.response.CarDto;
import com.molichuxing.services.infrastructure.dto.response.DealerDto;
import com.molichuxing.services.infrastructure.dto.response.EntrepotStorageDto;
import com.molichuxing.services.infrastructure.dto.response.IovFenceDto;
import com.molichuxing.services.infrastructure.dto.response.IovMileageDto;
import com.molichuxing.services.infrastructure.dto.response.OrderDealerDeliveryDto;
import com.molichuxing.services.infrastructure.dto.response.OrderDealerDetailBasicDto;
import com.molichuxing.services.infrastructure.dto.response.OrderDealerDetailStartDto;
import com.molichuxing.services.infrastructure.dto.response.RiskEmailDto;
import com.molichuxing.services.infrastructure.dto.response.StockCarDto;
import com.molichuxing.services.infrastructure.dto.response.StockStoreDto;
import com.molichuxing.services.infrastructure.dto.response.StoreDetailDto;
import com.molichuxing.services.infrastructure.dto.response.SubcompanyDto;
import com.molichuxing.services.infrastructure.dto.response.VehicleColorDto;
import com.molichuxing.services.infrastructure.service.CarFenceExceptionService;
import com.molichuxing.services.infrastructure.service.CarService;
import com.molichuxing.services.infrastructure.service.DealerService;
import com.molichuxing.services.infrastructure.service.EntrepotStorageService;
import com.molichuxing.services.infrastructure.service.IovCarService;
import com.molichuxing.services.infrastructure.service.IovFenceService;
import com.molichuxing.services.infrastructure.service.OrderDealerDeliveryService;
import com.molichuxing.services.infrastructure.service.OrderDealerService;
import com.molichuxing.services.infrastructure.service.OrderStatusFlowService;
import com.molichuxing.services.infrastructure.service.RiskEmailService;
import com.molichuxing.services.infrastructure.service.StockCarService;
import com.molichuxing.services.infrastructure.service.StockStoreService;
import com.molichuxing.services.infrastructure.service.StoreDetailService;
import com.molichuxing.services.infrastructure.service.SubcompanyService;
import com.molichuxing.services.infrastructure.service.VehicleColorService;
import com.molichuxing.services.property.OrderDealerSendCarStatusEnum;
import com.molichuxing.services.property.OrderDealerStatusEnum;
import com.molichuxing.services.property.OrderRequestTypeEnum;
import com.molichuxing.services.property.RiskEmailReceiveTypeEnum;
import com.molichuxing.services.property.RiskEmailTypeEnum;
import com.molichuxing.services.property.StockCarStockTypeEnum;

/**
 * @Author: renzhengyu
 * @Description:
 * @Date: Created in 10:53 2019/9/10
 * @Modified By:
 **/
@Service("orderDealerBffService")
public class OrderDealerBffServiceImpl implements OrderDealerBffService {
    private static final Logger logger = LoggerFactory.getLogger(OrderDealerBffServiceImpl.class);


    @Value("${email_account}")
    private String EMAIL_ACCOUNT;

    @Value("${email_password}")
    private String EMAIL_PASSWORD;

    @Value("${order.dealer.change.url}")
    private String ORDER_DEALER_CHANGE_URL;

    @Resource
    private OrderDealerBizService orderDealerBizService;

    @Resource
    private DealerService dealerService;

    @Resource
    private CarService carService;

    @Resource
    private VehicleBizService vehicleBizService;

    @Resource
    private SubcompanyService subcompanyService;

    @Resource
    private OrderDealerService orderDealerService;

    @Resource
    private OrderTradeFlowBizService orderTradeFlowBizService;

    @Resource
    private VehicleColorService vehicleColorService;

    @Resource
    private OrderDealerDeliveryService orderDealerDeliveryService;

    @Resource
    private StockCarBizService stockCarBizService;

    @Resource
    private OrderStatusFlowService orderStatusFlowService;

    @Resource
    private TokenUtil tokenUtil;

    @Resource
    private ContractBizService contractBizService;

    @Resource
    private StockStoreService stockStoreService;

    @Resource
    private IovCarService iovCarService;


    @Resource
    private IovFenceService iovFenceService;

    @Resource
    private EntrepotStorageService entrepotStorageService;

    @Resource
    private StoreDetailService storeDetailService;

    @Resource
    private StockCarService stockCarService;

    @Resource
    private RiskEmailService riskEmailService;
    
    @Resource
    private CarFenceExceptionService carFenceExceptionService;

    /**
     * 经销商列表
     * @param params
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public Paged<OrderDealerVo> orderDealerList(Map<String, Object> params, Integer pageNum, Integer pageSize) throws Exception {
        //获取当前登录的经销商id
        Integer dealerId = RequestAttrUtil.getCurrentDealerId();
        if(null == dealerId){
            throw new Exception("非法入参");
        }
        //经销商id
        params.put("dealerId",dealerId);
        Paged<OrderDealerVo> orderDealerVoPage = new Paged<>(null, 0, pageSize);
        Paged<OrderDealerBizDto> orderDealerBizDtoPage = orderDealerBizService.getOrderDealerBusList(params, pageNum, pageSize, OrderRequestTypeEnum.DEALER);
        if (null == orderDealerBizDtoPage) {
            return orderDealerVoPage;
        }
        BeanUtils.copyProperties(orderDealerBizDtoPage, orderDealerVoPage);
        if (null == orderDealerBizDtoPage.getList() || orderDealerBizDtoPage.getList().size()<= 0) {
            return orderDealerVoPage;
        }
        List<OrderDealerVo> orderDealerVoList = new ArrayList<>();
        OrderDealerVo orderDealerVo = null;
        List<OrderDealerCarVo> carInfoList = null;
        String vehicleName;
        for (OrderDealerBizDto orderDealerBizDto : orderDealerBizDtoPage.getList()) {
            orderDealerVo = new OrderDealerVo();
            BeanUtils.copyProperties(orderDealerBizDto, orderDealerVo);
            orderDealerVo.setOrderStatusName(OrderDealerStatusEnum.getName(orderDealerBizDto.getOrderStatus()));
            orderDealerVo.setOrderCode(orderDealerBizDto.getOrderCode());
            //总金额=总保证金+总租金
            orderDealerVo.setRentAmount(orderDealerBizDto.getRentAmount().add(orderDealerBizDto.getDepositAmount()));
            DealerDto dealerDto = dealerService.getDealerById(orderDealerBizDto.getDealerId());
            if(null == dealerDto){
                throw new Exception("非法入参");
            }
            orderDealerVo.setDealerName(dealerDto.getShortName());
            //查询车辆信息
            carInfoList =new ArrayList<>();
            OrderDealerCarVo orderDealerCarVo = null;
            for (Integer carId:orderDealerVo.getCarIdList()) {
                orderDealerCarVo = new OrderDealerCarVo();
                //获取车辆基础信息
                CarDto carDto = carService.getCarById(carId);
                if(null == carDto){
                    throw new Exception("非法入参");
                }
                //获取车型名称
                vehicleName = vehicleBizService.getVehicleName(carDto.getVehicleId());
                if(null == vehicleName){
                    throw new Exception("非法入参");
                }
                orderDealerCarVo.setLicencePlate(carDto.getLicencePlate());
                orderDealerCarVo.setVin(carDto.getVin());
                orderDealerCarVo.setVehicleName(vehicleName);
                carInfoList.add(orderDealerCarVo);
            }
            orderDealerVo.setCarInfoList(carInfoList);
            orderDealerVoList.add(orderDealerVo);
        }
        orderDealerVoPage.setList(orderDealerVoList);
        return orderDealerVoPage;
    }


    /**
     * 采购单流转状态
     * @param orderCode
     * @return
     */
    @Override
    public OrderDealerStatusInfoVo getDealerOrderFlow(Long orderCode) throws Exception {
        OrderDealerStatusInfoVo orderDealerStatusInfoVo =null;
        OrderDealerStatusInfoBizDto orderDealerStatusInfoBizDto = orderTradeFlowBizService.getDealerOrderStatusFlow(orderCode);
        if(null == orderDealerStatusInfoBizDto ){
            return orderDealerStatusInfoVo;
        }
        orderDealerStatusInfoVo = new OrderDealerStatusInfoVo();
        BeanUtils.copyProperties(orderDealerStatusInfoBizDto, orderDealerStatusInfoVo);

        List<OrderDealerStatusVo> orderDealerStatusVoList = new ArrayList<>();
        OrderDealerStatusVo orderDealerStatusVo = null;
        for (OrderDealerStatusBizDto orderDealerStatusBizDto:orderDealerStatusInfoBizDto.getOrderDealerStatusList()) {
            orderDealerStatusVo = new OrderDealerStatusVo();
            BeanUtils.copyProperties(orderDealerStatusBizDto, orderDealerStatusVo);
            orderDealerStatusVoList.add(orderDealerStatusVo);
        }
        orderDealerStatusInfoVo.setOrderDealerStatusList(orderDealerStatusVoList);

        return orderDealerStatusInfoVo;
    }


    /**
     * 采购单基础信息
     * @param orderCode
     * @return
     */
    @Override
    public OrderDealerDetailBasicVo orderDetailBasic(Long orderCode) throws Exception {
        OrderDealerDetailBasicVo  orderDealerDetailBasicVo= null;
        //查询采购单基础信息详情
        OrderDealerDetailBasicDto orderDealerDetailBasicDto = orderDealerService.getDetailBasic(orderCode);
        if (null == orderDealerDetailBasicDto) {
            throw new Exception("非法入参");
        }
        orderDealerDetailBasicVo= new OrderDealerDetailBasicVo();
        BeanUtils.copyProperties(orderDealerDetailBasicDto,orderDealerDetailBasicVo);

        // 获取采购单合同信息  入参：订单号       出参：[合同名称，合同地址]
        ContractPurchaseBizDto contractPurchaseBizDto = contractBizService.getPurchaseContract(orderCode);
        if(null != contractPurchaseBizDto && null != contractPurchaseBizDto.getList() && contractPurchaseBizDto.getList().size() > 0){
            List<OrderDealerContractVo> contractList = new ArrayList<>();
            OrderDealerContractVo orderDealerContractVo = null;
            for (ContractImageBizDto contractImageBizDto:contractPurchaseBizDto.getList()) {
                orderDealerContractVo = new OrderDealerContractVo();
                orderDealerContractVo.setContractName(contractImageBizDto.getName());
                orderDealerContractVo.setContractUrl(contractImageBizDto.getPath());
                contractList.add(orderDealerContractVo);
            }
            orderDealerDetailBasicVo.setContractList(contractList);
        }

        //获取分子公司名称
        SubcompanyDto subcompanyDto = subcompanyService.getSubcompanyNameById(orderDealerDetailBasicDto.getSubCompanyId());
        if(null == subcompanyDto){
            throw new Exception("非法入参");
        }
        orderDealerDetailBasicVo.setSubCompanyName(subcompanyDto.getName());
        orderDealerDetailBasicVo.setContractSignDate(orderDealerDetailBasicDto.getContractSignDate().toLocalDate());
        return orderDealerDetailBasicVo;
    }


    /**
     * 采购单车辆信息&发车信息
     * @param orderCode
     * @return
     */
    @Override
    public OrderDealerDetailVehicleVo orderDetailVehicle(Long orderCode) throws Exception {
        OrderDealerDetailVehicleVo orderDealerDetailVehicleVo = null;
        //查询车辆信息和发车信息
        OrderDealerDeliveryBizDto orderDealerDeliveryBizDto = orderDealerBizService.getOrderDetailCarsInfo(orderCode);
        if (null == orderDealerDeliveryBizDto || null == orderDealerDeliveryBizDto.getOrderDealerDetailCarInfoList() || orderDealerDeliveryBizDto.getOrderDealerDetailCarInfoList().size() <= 0 ) {
            throw new Exception("非法入参");
        }
        orderDealerDetailVehicleVo = new OrderDealerDetailVehicleVo();
        List<OrderDealerDetailCarInfoVo> orderDealerDetailCarInfoVoList = new ArrayList<>();
        OrderDealerDetailCarInfoVo orderDealerDetailCarInfoVo = null;
        String vehicleName = null;
        //总租金
        BigDecimal sumRent = new BigDecimal("0");
        //总保证金
        BigDecimal sumDeposit = new BigDecimal("0");
        Map<Integer,Integer> vehicleTypeCount = new HashMap<>();
        Integer carCount;
        for (OrderDealerDetailCarInfoBizDto orderDealerDetailCarInfoBizDto:orderDealerDeliveryBizDto.getOrderDealerDetailCarInfoList()) {
            orderDealerDetailCarInfoVo =new OrderDealerDetailCarInfoVo();
            BeanUtils.copyProperties(orderDealerDetailCarInfoBizDto,orderDealerDetailCarInfoVo);
            //获取车辆基础信息
            CarDto carDto = carService.getCarById(orderDealerDetailCarInfoBizDto.getCarId());
            if(null == carDto){
                throw new Exception("非法入参");
            }
            //获取车型名称
            vehicleName = vehicleBizService.getVehicleName(carDto.getVehicleId());
            if(null == vehicleName){
                throw new Exception("非法入参");
            }
            //获取车身颜色
            VehicleColorDto vehicleColorDto = vehicleColorService.getVehicleColorByvehicleColorId(carDto.getVehicleColorId());
            if(null == vehicleColorDto){
                throw new Exception("非法入参");
            }
            orderDealerDetailCarInfoVo.setVehicleName(vehicleName);
            //计算车型对应的车辆数
            if(null == vehicleTypeCount.get(carDto.getVehicleId())){
                vehicleTypeCount.put(carDto.getVehicleId(),1);
            }else{
                carCount = vehicleTypeCount.get(carDto.getVehicleId());
                vehicleTypeCount.put(carDto.getVehicleId(),++carCount);
            }

            orderDealerDetailCarInfoVo.setVin(carDto.getVin());
            orderDealerDetailCarInfoVo.setVehicleId(carDto.getVehicleId());
            orderDealerDetailCarInfoVo.setLicencePlate(carDto.getLicencePlate());
            orderDealerDetailCarInfoVo.setVehicleColor(vehicleColorDto.getName());
            sumRent = sumRent.add(orderDealerDetailCarInfoBizDto.getRent());
            sumDeposit = sumDeposit.add(orderDealerDetailCarInfoBizDto.getDeposit());
            orderDealerDetailCarInfoVo.setDrivingMileage(orderDealerDetailCarInfoBizDto.getTotalMileage());
            orderDealerDetailCarInfoVoList.add(orderDealerDetailCarInfoVo);
        }

        List<OrderDealerDetailCarInfoVo> orderDealerCarCountVoList = new ArrayList<>();
        for (OrderDealerDetailCarInfoVo orderDealerCarCountVo:orderDealerDetailCarInfoVoList) {
            orderDealerCarCountVo.setCarCount(vehicleTypeCount.get(orderDealerCarCountVo.getVehicleId()));
            orderDealerCarCountVoList.add(orderDealerCarCountVo);
        }
        orderDealerDetailVehicleVo.setOrderDealerDetailCarInfoList(orderDealerCarCountVoList);
        orderDealerDetailVehicleVo.setTotalVehicleInfo(orderDealerCarCountVoList.size());
        orderDealerDetailVehicleVo.setSumRent(sumRent);
        orderDealerDetailVehicleVo.setSumDeposit(sumDeposit);

        if(null != orderDealerDeliveryBizDto.getOrderDealerDetailStartList() && orderDealerDeliveryBizDto.getOrderDealerDetailStartList().size() > 0){
            List<OrderDealerDetailStartVo> orderDealerDetailStartList = new ArrayList<>();
            OrderDealerDetailStartVo orderDealerDetailStartVo= null;
            for (OrderDealerDetailStartBizDto orderDealerDetailStartBizDto:orderDealerDeliveryBizDto.getOrderDealerDetailStartList()) {
                orderDealerDetailStartVo = new OrderDealerDetailStartVo();
                BeanUtils.copyProperties(orderDealerDetailStartBizDto,orderDealerDetailStartVo);
                //获取车辆基础信息
                CarDto carDto = carService.getCarById(orderDealerDetailStartVo.getCarId());
                if(null == carDto){
                    throw new Exception("非法入参");
                }
                //获取车型名称
                vehicleName = vehicleBizService.getVehicleName(carDto.getVehicleId());
                if(null == vehicleName){
                    throw new Exception("非法入参");
                }
                //获取车身颜色
                VehicleColorDto vehicleColorDto = vehicleColorService.getVehicleColorByvehicleColorId(carDto.getVehicleColorId());
                if(null == vehicleColorDto){
                    throw new Exception("非法入参");
                }
                orderDealerDetailStartVo.setVin(carDto.getVin());
                orderDealerDetailStartVo.setLicencePlate(carDto.getLicencePlate());
                orderDealerDetailStartVo.setVehicleColor(vehicleColorDto.getName());
                orderDealerDetailStartVo.setVehicleName(vehicleName);

                orderDealerDetailStartList.add(orderDealerDetailStartVo);
            }
            orderDealerDetailVehicleVo.setTotalVehicle(orderDealerDeliveryBizDto.getOrderDealerDetailStartList().size());
            orderDealerDetailVehicleVo.setOrderDealerDetailStartList(orderDealerDetailStartList);

        }


        return orderDealerDetailVehicleVo;
    }

    /**
     * 车辆拒收
     * @param orderCode
     * @param carId
     * @param rejectReason
     * @return
     * @throws Exception
     */
    @Override
    public Boolean orderDealerCarRefuse(Long orderCode, Integer carId, String rejectReason) throws Exception {
        Boolean ret = false;
        RefuseModifyFto refuseModifyFto = new RefuseModifyFto();
        refuseModifyFto.setCarId(carId);
        refuseModifyFto.setOrderCode(orderCode);
        refuseModifyFto.setRejectReason(rejectReason);

        ret = orderDealerDeliveryService.modifyCarRefuseStatus(refuseModifyFto);

        //查询车辆
        CarDto carDto = carService.getCarById(carId);
        //查询订单信息
        OrderDealerDetailBasicDto orderDealerDetailBasicDto = orderDealerService.getDetailBasic(orderCode);
        //查询经销商简称
        DealerDto dealerDto = dealerService.getDealerById(orderDealerDetailBasicDto.getDealerId());
        if(null != dealerDto || null !=dealerDto.getShortName()){
            List<String> emails = null;
            //邮件
            emails = getEmail(RiskEmailTypeEnum.ORDER_DEALER_REJECTION_PAYMENT); // getRiskEmailList(RiskEmailEnum.ONE.getValue());
            if(null != emails){
                EmailUtil.sendMail(EMAIL_ACCOUNT, EMAIL_PASSWORD,
                        EmailSubjectEnum.BUSINESS_DEALER_REJECTION.getName(),
                        EmailTemplateEnum.BUSINESS_DEALER_REJECTION.getTemplate()
                                .replace("$【name】", dealerDto.getShortName())
                                .replace("$【orderCode】", String.valueOf(orderCode))
                                .replace("$【licencePlate】", carDto.getLicencePlate()),
                        emails);
            }else{
                logger.error("拒收车辆 未配置发送邮件人员的邮箱信息");
            }
        }

        // 钉钉
        DingTalkUtil.execute( ORDER_DEALER_CHANGE_URL,
                EmailTemplateEnum.BUSINESS_DEALER_REJECTION.getTemplate()
                        .replace("$【name】", dealerDto.getShortName())
                        .replace("$【orderCode】", String.valueOf(orderCode))
                        .replace("$【licencePlate】", carDto.getLicencePlate()));
        return ret;
    }

    /**
     * 保存收车单
     * @return
     * @throws Exception
     */
    @Override
    public Boolean modifyDeliverySlip(OrderDeliverySlipModifyVo orderDeliverySlipModifyVo) throws Exception {

        //查询账号是否存在
        UserEntity currentLoginUser = tokenUtil.getUser();
        if(null == currentLoginUser){
            throw new Exception("用户未登录");
        }

        //保存交车单-将车辆状态改为已收车
        DeliverySlipModifyDto deliverySlipModifyDto = new DeliverySlipModifyDto();
        deliverySlipModifyDto.setOrderCode(orderDeliverySlipModifyVo.getOrderCode());
        deliverySlipModifyDto.setCarId(orderDeliverySlipModifyVo.getCarId());
        deliverySlipModifyDto.setDeliveryUrl(orderDeliverySlipModifyVo.getDeliveryUrl());
        //获取当前已行驶里程
        ResponseResult<Map<String, IovMileageDto>> iovMap = iovCarService.getMileageByVins(Arrays.asList(orderDeliverySlipModifyVo.getVin()));
        if (!iovMap.getCode().equals(0)) {
            throw new Exception("获取当前已行驶里程失败");
        }
        deliverySlipModifyDto.setDrivingMileage(iovMap.getData().get(orderDeliverySlipModifyVo.getVin()).getOdo());

        Boolean ret = orderDealerDeliveryService.modifyDeliverySlip(deliverySlipModifyDto);
        if(!ret){
            throw new Exception("收车失败");
        }
        //车辆入库
        StockCarBizModifyDto stockCarBizModifyDto = new StockCarBizModifyDto();
        stockCarBizModifyDto.setCarId(orderDeliverySlipModifyVo.getCarId());
        stockCarBizModifyDto.setStorageTime(LocalDateTime.now());
        //获取登录用户信息  操作人id，操作人名称
        stockCarBizModifyDto.setAccountId(currentLoginUser.getAccountId());
        stockCarBizModifyDto.setAccountAccount(currentLoginUser.getRealName());
        Boolean flag = stockCarBizService.modifyCollectStoreStock(stockCarBizModifyDto);
        if(!flag){
            throw new Exception("收车失败");
        }

        OrderDealerDeliveryDto orderDealerDeliveryDto = orderDealerDeliveryService.getOrderDealerDeliveryInfo(orderDeliverySlipModifyVo.getOrderCode(), orderDeliverySlipModifyVo.getCarId());
        if(null == orderDealerDeliveryDto){
            throw new Exception("非法入参");
        }
        StockStoreDto stockStoreDto = stockStoreService.getStockStoreByStoreId(orderDealerDeliveryDto.getStoreId());
        if(null == stockStoreDto ){
            throw new Exception("库存id为空");
        }
        //维护车辆表 车辆所在仓库
        carService.modifyStockIdById(orderDeliverySlipModifyVo.getCarId(),stockStoreDto.getStockId(), StockCarStockTypeEnum.STORE.getValue());

        //查询订单下所有发车状态
        List<Integer> sendStatusList =  orderDealerDeliveryService.getSendStatusByOrderCode(orderDeliverySlipModifyVo.getOrderCode());
        if(null == sendStatusList || sendStatusList.size() <= 0){
            throw new Exception("非法入参");
        }
        int count = 0;
        for (Integer sendStatus: sendStatusList) {
            if(sendStatus != OrderDealerSendCarStatusEnum.RECEIVED.getValue()){
                count++;
                continue;
            }
        }

        //如果该订单下所有车辆的收车状态都为已收车时，将订单状态改为 完成采购
        if(count == 0){
            Boolean modifyOrderStatus = orderDealerService.modifyOrderStatus(orderDeliverySlipModifyVo.getOrderCode(), OrderDealerStatusEnum.COMPLETE.getValue());

            OrderStatusFlowCreateDto orderStatusFlowCreateDto= new OrderStatusFlowCreateDto();
            orderStatusFlowCreateDto.setOrderCode(orderDeliverySlipModifyVo.getOrderCode());
            orderStatusFlowCreateDto.setOrderStatus(OrderDealerStatusEnum.COMPLETE.getValue());
            // 获取登录用户信息  操作人id，操作人名称，操作人类型，
            orderStatusFlowCreateDto.setOrderUserId(currentLoginUser.getAccountId());
            orderStatusFlowCreateDto.setOrderModifiedType(currentLoginUser.getSystemType().getValue());
            orderStatusFlowCreateDto.setOrderUserName(currentLoginUser.getRealName());
            //订单流转状态插入
            Boolean createOrderStatusFlow =orderStatusFlowService.createOrderStatusFlow(orderStatusFlowCreateDto);
            if(!modifyOrderStatus || !createOrderStatusFlow){
                return false;
            }
        }
        StockCarDto stockCarDto = getStockCarDto(orderDeliverySlipModifyVo.getCarId());
        
        CarDto carDto = getCarDto(orderDeliverySlipModifyVo.getCarId());
        
        //围栏验证
        getBindingFenceVerify(carDto, stockCarDto, "车辆已经绑定其它围栏");
        //车辆绑定门店围栏
        createBindingFence(stockCarDto.getFenceId(),orderDeliverySlipModifyVo.getVin());

        return true;
    }

    /**
	 * 获取车辆信息
	 * @param carId
	 * @return
	 */
    private CarDto getCarDto(Integer carId) {
    	CarDto carDto = carService.getCarById(carId);
		if(null == carDto) {
			throw new BizException("不存在该车辆信息");
		}
		return carDto;
    }
    
    /**
	 * 验证围栏
	 * @param carDto
	 * @param stockCarDto
	 * @param exceptionStr
	 */
	private void getBindingFenceVerify(CarDto carDto,StockCarDto stockCarDto,String exceptionStr) {
		Integer carId=carDto.getId();
		// 调取车联网接口 根据车辆VIN 获取围栏id
        List<String> vinList = new ArrayList<>(1);
        vinList.add(carDto.getVin());
        Map<String, List<IovFenceDto>> fenceMap = iovFenceService.getFenceByVins(vinList);

        //判断车联网接口返回围栏信息是否为空
        if(fenceMap != null && fenceMap.get(carDto.getVin()) != null && fenceMap.get(carDto.getVin()).size() > 0){
            //新增车辆围栏异常 车辆已经绑定围栏
            FenceExceptionCreateDto fenceExceptionCreateDto = new FenceExceptionCreateDto();
            fenceExceptionCreateDto.setCarId(carId);
            fenceExceptionCreateDto.setFenceId(stockCarDto.getFenceId());
            fenceExceptionCreateDto.setType(carDto.getStockType());
            fenceExceptionCreateDto.setStockId(carDto.getStockId());
            fenceExceptionCreateDto.setExplain(exceptionStr);
            carFenceExceptionService.createCarFenceException(fenceExceptionCreateDto);
            throw new BizException(101,exceptionStr);
        }
        
	}

    /**
     * 采购单收车列表
     * @param orderCode
     * @param carStatus
     * @return
     * @throws Exception
     */
    @Override
    public Paged<OrderDealerDetailStartVo> orderDealerStartList(Long orderCode, Integer carStatus) throws Exception {
        Paged<OrderDealerDetailStartVo> orderDealerDetailStartVoPaged = new Paged<>();
        List<OrderDealerDetailStartVo> orderDealerDetailStartVoList = new ArrayList<>();

        List<TabDto> tabDto = orderDealerDeliveryService.getDetailStartCountDto(orderCode);
        if(null == tabDto){
            throw new Exception("非法入参");
        }
        orderDealerDetailStartVoPaged.setTab(tabDto);
        List<OrderDealerDetailStartDto> orderDealerDetailStartDtoList = orderDealerDeliveryService.getDetailStartDto(orderCode,carStatus);
        if(null == orderDealerDetailStartDtoList || orderDealerDetailStartDtoList.size() <= 0){
            return orderDealerDetailStartVoPaged;
        }
        OrderDealerDetailStartVo orderDealerDetailStartVo = null;
        String vehicleName = null;
        for (OrderDealerDetailStartDto orderDealerDetailStartDto: orderDealerDetailStartDtoList) {
            orderDealerDetailStartVo = new OrderDealerDetailStartVo();
            BeanUtils.copyProperties(orderDealerDetailStartDto,orderDealerDetailStartVo);
            //获取车辆基础信息
            CarDto carDto = carService.getCarById(orderDealerDetailStartDto.getCarId());
            if(null == carDto){
                throw new Exception("车辆基础信息为空");
            }
            orderDealerDetailStartVo.setCarId(orderDealerDetailStartDto.getCarId());
            orderDealerDetailStartVo.setVin(carDto.getVin());
            orderDealerDetailStartVo.setLicencePlate(carDto.getLicencePlate());
            //获取车型名称
            vehicleName = vehicleBizService.getVehicleName(carDto.getVehicleId());
            if(null == vehicleName){
                throw new Exception("车型信息为空");
            }
            orderDealerDetailStartVo.setVehicleName(vehicleName);
            orderDealerDetailStartVoList.add(orderDealerDetailStartVo);
        }
        orderDealerDetailStartVoPaged.setList(orderDealerDetailStartVoList);
        return orderDealerDetailStartVoPaged;
    }




    /**
     * 围栏绑定
     * @param fenceId
     * @param vin
     * @return
     */
    private Boolean createBindingFence(Integer fenceId,String vin) {
        IovFenceBindingCreateDto dto = new IovFenceBindingCreateDto();
        if(null == fenceId || StringUtils.isAllBlank(vin)) {
            return false;
        }
        dto.setFenceId(Long.valueOf(fenceId));
        List<String> list= new ArrayList<>(1);
        list.add(vin);
        dto.setListVin(list);
        try {
            return iovFenceService.addBindingFence(dto);
        }catch (Exception e) {
            logger.error("围栏绑定异常：",e);
            return false;
        }
    }

    /**
     * 解绑围栏
     * @param fenceId
     * @param vin
     * @return
     */
    private Boolean modifyBindingFence(Integer fenceId,String vin) {
        IovFenceBindingModifyDto dto = new IovFenceBindingModifyDto();
        if(null == fenceId || StringUtils.isAllBlank(vin)) {
            return false;
        }
        dto.setFenceId(Long.valueOf(fenceId));
        List<String> list= new ArrayList<>(1);
        list.add(vin);
        dto.setListVin(list);
        try {
            return iovFenceService.modifyBindingFence(dto);
        }catch (Exception e) {
            logger.error("解绑围栏异常：",e);
            return false;
        }
    }


    /**解除仓库围栏
     * @param stockId
     * @param vin
     */
    private void modifyFenceStock(Integer stockId,String vin){
        EntrepotStorageDto entrepotStorage = getEntrepotStorage(stockId);
        Boolean flag = modifyBindingFence(entrepotStorage.getFenceId(), vin);
        if(!flag) {
            throw new BizException("车联网解除仓库围栏失败!");
        }
    }

    /**
     * 车辆绑定门店围栏
     * @param stockId
     * @param vin
     */
    private void createFenceStore(Integer stockId,String vin) {
        StockStoreDto  stockStoreDto = getStockStore(stockId);
        StoreDetailDto store = getStoreDetailById(stockStoreDto.getStoreId());
        Boolean flag = createBindingFence(store.getFenceId(),vin);
        if(!flag) {
            throw new BizException("车联网车辆绑定门店围栏失败!");
        }
    }

    /**
     * 根据中转库id查询中转库信息
     * @param stockId
     * @return
     */
    private EntrepotStorageDto getEntrepotStorage(Integer stockId) {
        EntrepotStorageDto entrepotStorage = entrepotStorageService.getEntrepotStorage(stockId);
        if(null == entrepotStorage) {
            throw new BizException("不存在该中转库信息");
        }
        return entrepotStorage;
    }

    /**
     * 根据门店id获取门店信息
     * @param storeId
     * @return
     */
    private StoreDetailDto getStoreDetailById(Integer storeId) {
        try {
            StoreDetailDto store = storeDetailService.getStoreDetailById(storeId);
            if(null == store) {
                throw new BizException("不存在该门店信息");
            }
            return store;
        } catch (Exception e) {
            logger.error("根据门店id获取门店信息异常：",e);
            throw new BizException("门店服务异常");
        }
    }

    /**
     * 根据车辆id获取库存信息
     * @param carId
     * @return
     */
    private StockCarDto getStockCarDto(Integer carId) {
        StockCarDto stockCarDto = stockCarService.getStockCar(carId);
        if(null == stockCarDto) {
            throw new BizException(101, "不存在该条信息");
        }
        return stockCarDto;
    }

    /**
     * 根据仓库id 查询门店id
     * @param stockId
     * @return
     */
    private StockStoreDto getStockStore(Integer stockId) {
        //根据仓库id 查询门店id
        StockStoreDto stockStore = stockStoreService.getStockStore(stockId);
        if(null == stockStore ) {
            throw new BizException("该仓库没有门店信息");
        }
        return stockStore;
    }

    /**
     * 获取邮件人信息
     * @return
     */
    private List<String> getEmail(RiskEmailTypeEnum riskEmailTypeEnum){
        List<RiskEmailDto> riskList = riskEmailService.getByType(riskEmailTypeEnum.getValue(),RiskEmailReceiveTypeEnum.EMAIL_RECIPIENT.getValue());
        List<String> list=null;
        if(null != riskList && !riskList.isEmpty()) {
            list=new ArrayList<>();
            for (RiskEmailDto dto : riskList) {
                list.add(dto.getEmail());
            }
        }
        return list;
    }
}
